package com.ruoyi;

import com.fasterxml.jackson.databind.JsonNode;
import com.ruoyi.common.utils.file.FileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 统计代码行数
 */
@Slf4j
public class StatCodeCountMain {

    private static ExecutorService executor = Executors.newFixedThreadPool(200); // 根据任务量调整线程数

    private static ExecutorService callbackExecutor = Executors.newSingleThreadExecutor(); // 根据任务量调整线程数

    public static String getProjectRootPath() {
        try {
            // 获取项目根目录，target/classes 所在的上级目录就是项目根目录
            File file = ResourceUtils.getFile("classpath:");
            String absolutePath = file.getParentFile().getParentFile().getAbsolutePath();
            int lastIndexOf = absolutePath.lastIndexOf(File.separator);
            return absolutePath.substring(0, lastIndexOf);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String getCurFilePackagePath(Class<?> clazz) {
        // 获取包对象
        Package pkg = clazz.getPackage();

        // 获取包名（包路径，以"."分隔）
        String packageName = pkg.getName();
        log.info("当前类的包名（包路径）：{}", packageName);

        // 如果需要将包名转换为文件系统路径（以"/"分隔）
        String packagePath = packageName.replace(".", File.separator);
        log.info("当前类的包路径：{}", packagePath);
        return packagePath;
    }


    public static void main(String[] args) {

        long start = System.currentTimeMillis();

        String projectRootPath = getProjectRootPath();
        log.info("projectRootPath:{}", projectRootPath);

        String curFilePackagePath = getCurFilePackagePath(StatCodeCountMain.class);
        log.info("curFilePackagePath:{}", curFilePackagePath);

//        String path = projectRootPath + File.separator +"src\\main\\java\\com\\laozj\\example";
//        String path = projectRootPath + File.separator +"src\\main\\java" + File.separator + curFilePackagePath;
//        String path = projectRootPath + File.separator;
        String path = "E:\\code\\iDCOS" + File.separator;
        List<Path> dirFile = FileUtils.getDirFile(Paths.get(path), true, false);


        AtomicInteger count = new AtomicInteger();
        List<CompletableFuture<Void>> futureList = new ArrayList<>();
        for (Path dirPath : dirFile) {
            log.info("dirPath:{}", dirPath);
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {

                List<Path> fileList = FileUtils.getDirFile(dirPath, false, true);

                for (Path filePath : fileList) {
                    if(filePath.toString().contains("target") || filePath.toString().contains(".git") || filePath.toString().contains("node_modules")
                            || filePath.toString().contains(".gitignore")){
                        continue;
                    }
                    Integer rowCount = FileUtils.readFileRowCount(filePath.toString());
                    log.info("filePath:{}，行数：{}", filePath,rowCount);
                    count.addAndGet(rowCount);
                }
            },executor);
            futureList.add( future);
        }

        // 等待所有任务完成（返回一个 CompletableFuture<Void>）
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(
                futureList.toArray(new CompletableFuture[0]) // 转换为数组
        );

        // 等待所有任务完成
//        allFutures.join();

//        // 所有任务完成后，收集结果
        CompletableFuture<Void> finalFuture = allFutures.thenRunAsync(() -> {
            // 这里可以做任务完成后的逻辑，比如打印总行数
            log.info("所有任务执行完毕，总行数：{}", count.get());
            log.info("耗时：{}", System.currentTimeMillis() - start);
        }, callbackExecutor);

//        finalFuture.join();
//
//
//        log.info("项目当前代码行数 count:{}", count.get());
//        log.info("耗时：{}", System.currentTimeMillis() - start);
    }
}
